feat: route profile URLs to njump.me for non-Divine users#47
feat: route profile URLs to njump.me for non-Divine users#47NotThatKindOfDrLiz merged 15 commits intomainfrom
Conversation
useAuthor now tracks whether Funnelcake REST succeeded (isFunnelcakeUser). Profile links in report views use divine.video when the user is indexed by Funnelcake, njump.me otherwise. Avoids sending moderators to empty profile pages for Nostr users who never used Divine. Category A call sites updated: UserIdentifier, ReporterCard, ReporterInfo, UserProfilePreview. Category B deferred (no regression).
7ad17e2 to
9d9b1f6
Compare
Shows a small ExternalLink icon next to usernames when the profile link goes to njump.me instead of divine.video. Gives moderators an at-a-glance signal that the reporter or reported user is not on our relay.
…ents Category B components now use getProfileUrl with isFunnelcakeUser: - ThreadContext PostCard: external icon on thread ancestor authors - ThreadModal ThreadPost: external icon on full thread post authors - EventsList EventRow: external icon on event list authors - BannedUserCard: defaults to njump (no Funnelcake signal available) - UserProfileCard: defaults to njump (receives props, no hook) All getDivineProfileUrl call sites migrated. Function kept in constants for backward compatibility.
ExternalLink arrow was ambiguous (looks like a generic link indicator). Globe icon in purple clearly signals 'broader Nostr network'. Added 'Nostr' badge on ReporterInline for reporters, matching the existing trust-level badge pattern.
Recent Content now fetches videos (34235/34236), comments (1111), and text notes (1) instead of just kind 1. Each item shows a type badge: - Video (green) — visible in Divine apps - Comment (amber) — visible in Divine apps - Note (amber + warning) — 'Text note — not visible in Divine apps' Each item links to divine.video (videos) or njump.me (notes/comments) for context. Helps moderators understand what content is on the relay and whether Divine users can actually see it.
Both badges now link to the user's profile: - 'Divine' (green) links to divine.video/profile - 'Nostr' (purple) links to njump.me Shown on both reporter and reported user sections.
UserProfileCard (the actual reported user component in report detail) now receives isFunnelcakeUser from useReportContext. Shows green 'Divine' or purple 'Nostr' badge next to the user name, both clickable. Recent Content section now shows kind-aware badges: - Video (green) for kind 34235/34236 - Comment (amber) for kind 1111 - Note (amber + globe) for kind 1, with 'not visible in Divine apps' warning Each item links to divine.video (videos) or njump.me (notes).
Video: 'Short-form video — visible in Divine apps' Comment: 'Video comment — visible in Divine apps' Note: 'Text note (kind 1) — not visible in Divine apps. Only visible via external Nostr clients.' Removes the separate warning line under notes. Comment badge color changed to green (visible in Divine) to match Video.
Radix UI tooltips weren't appearing in Safari. Native HTML title attribute works reliably across all browsers and is accessible by default (read by screen readers as accessible description).
Previously most call sites passed useAuthor(pubkey) without apiUrl, so Funnelcake REST was never tried and isFunnelcakeUser was always false. Now the hook reads config.apiUrl from useAppContext as fallback, so all call sites get accurate Funnelcake detection without needing to pass apiUrl explicitly. Explicit override still supported.
Code reviewFound 1 issue:
divine-relay-manager/src/components/ReporterInfo.tsx Lines 98 to 100 in de5eff4 |
… false ReporterInfo was hardcoding getProfileUrl(npub, false), routing all reporters to njump.me. ReportedBy in the same file correctly reads isFunnelcakeUser from useAuthor -- now ReporterInfo does too.
NotThatKindOfDrLiz
left a comment
There was a problem hiding this comment.
I like the direction here. The core useAuthor + getProfileUrl approach is clean, and routing non-Divine users to njump.me solves a real moderator problem.
I do want to request two fixes before merge.
First, useAuthor now implicitly depends on the current environment's apiUrl, but the query key in src/hooks/useAuthor.ts still only keys on pubkey:
queryKey: ['author', pubkey ?? ''],That was fine before, but after this change callers that omit the override now fall back to config.apiUrl. If a moderator switches environments, TanStack Query can reuse a cached author result from the previous environment for the same pubkey, including the new isFunnelcakeUser flag. That creates exactly the kind of subtle misrouting this PR is trying to fix: profile links can point to the wrong destination for up to the cache lifetime. Please include apiUrl in the query key.
Second, the PR introduces new hardcoded production links for recent-content event URLs in UserProfileCard and UserProfilePreview:
https://divine.video/${...}This repo's rule is that domains come from config, not application code, and this is more than stylistic: in staging or local, these links will kick moderators out to production. ThreadContext already has the same hardcoded pattern, but this PR adds more of it, so I don't think we should expand that further. Please route these through an environment-aware helper instead of hardcoding divine.video.
A couple of quick notes on the rest:
- The
ReporterInfoissue looks fixed on the current head. - The broader recent-content UI work is useful, but it does make the PR a bit wider than the title suggests.
Requesting changes for the useAuthor cache key and the hardcoded production event links. Once those are fixed, I'm comfortable taking another look.
|
Picked this up and pushed the follow-up fix set on top of the branch ( What changed:
Local verification:
|
NotThatKindOfDrLiz
left a comment
There was a problem hiding this comment.
The follow-up fixes are in. The environment-sensitive caching and public-link routing issues are resolved, the PR diff is tighter, and the frontend checks I ran are clean.
Summary
njump.me/{npub}when the user isn't indexed by Funnelcake (i.e., their profile doesn't exist onrelay.divine.video). Previously all links went todivine.video/profile/{npub}, which is blank for non-Divine Nostr users.useAuthorhook now exposesisFunnelcakeUser: booleantracking whether the Funnelcake REST path succeeded. Zero new network requests -- just reads the result already being fetched.UserIdentifier,UserDisplayName,ReporterCard,ReporterInline,ReportedBy,UserProfilePreview. Category B (thread, events list, banned cards) deferred -- no regression, lower priority.Surfaced by Aleysha's Apr 2 report batch -- moderators were clicking through to empty Divine profile pages for users who only exist on external relays.
Test plan